//Copyright (C) 2010 Ron Coleman. Contact: ronncoleman@gmail.com
//
//This library is free software; you can redistribute it and/or
//modify it under the terms of the GNU General Public License
//as published by the Free Software Foundation; either
//version 3 of the License, or (at your option) any later version.
//
//This library is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with this library; if not, write to the Free Software
//Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

package org.workplicity.cia.table;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashSet;
import javax.swing.table.AbstractTableModel;
import org.workplicity.cia.util.CIAHelper;
import org.workplicity.elog.entry.ElogUser;
import org.workplicity.elog.entry.Handoff;
import org.workplicity.elog.repos.Handoffs;
import org.workplicity.util.DateFormatter;
import org.workplicity.util.Helper;
import org.workplicity.worklet.WorkletContext;

/**
 * This class is the table model for the handoffs
 * @author Ron Coleman
 */
public class HandoffsTableModel extends AbstractTableModel {
    protected ArrayList<Handoff> handoffs = new ArrayList<Handoff>( );

    /**
     * Column names
     */
    private String[] columnNames = {
        "Id",
        "Update",
        "From",
        "To",
        "Trade",
        "Description"
    };

    private long end;
    private long start;
    private ElogUser user;

    public int getRowCount() {
        return handoffs.size();
    }
    
    /**
     * Gets the name for a column.
     * @param col Column number.
     * @return Column name
     */
    @Override
    public String getColumnName(int col) {
        return columnNames[col];
    }
    public int getColumnCount() {
        return columnNames.length;
    }

    public Object getValueAt(int row, int col) {
        if(row < 0 || row >= handoffs.size())
            return null;

        Handoff handoff = handoffs.get(row);

        if(col == 0)
            return handoff.getId();

        if(col == 1)
            return DateFormatter.toString(handoff.getUpdateDate());

        if(col == 2)
            return CIAHelper.toUser(handoff.getFromId());

        if(col == 3)
        {
            if(handoff.getToId() == -1)
                return "N/A";
            else
                return CIAHelper.toUser(handoff.getToId());
        }

        if(col == 4)
        {
            if(handoff.getTradeId() == -1)
                return "N/A";
            else {
                return CIAHelper.toTrade(handoff.getTradeId());
            }
        }

        if(col == 5)
            return handoff.getMessage();
            
        return null;
    }

    /**
     * Gets a row in the table.
     * @param row Row index
     * @return handoff
     */
    public Handoff getRow(int row) {
        return handoffs.get(row);
    }

    public void refresh(ElogUser user)
    {
        this.user = user;

        // Gather up the users that are related to this user
        HashSet<ElogUser> pool = new HashSet<ElogUser>( );

        pool.add(user);
        
        CIAHelper.gatherSubordinates(user, pool);

        // Build the query criteria and collect the trades in the same loop
        HashSet<Integer> tradeIds = new HashSet<Integer>( );

        String criteria = "/list [";

        int count = 0;
        for(ElogUser auser : pool) {
            if(count != 0)
                criteria += " or ";
            else
                criteria += "(";

            criteria += "fromId = " + auser.getId() + " or toId = " + auser.getId();

            ++count;

            for(Integer id : auser.getTradeList())
                tradeIds.add(id);
        }


        // Add the trades to the criteria
        for(Integer id : tradeIds)
        {
            if(count != 0)
                criteria += " or ";
            else
                criteria += "(";

            criteria += "tradeId = " + id;

            count++;
        }

        // Add the time dimension
        if(count != 0)
            criteria += ") and ";

        criteria += "updateDate > " + start + " and updateDate <= " + end;
        
        criteria += " ]";

        // Retrieve the handoffs
        if(count == 0)
            return;
        
        handoffs = Helper.query(Handoffs.TITLE, criteria, WorkletContext.getInstance());

        // Sort them
        Collections.sort(handoffs, new Comparator() {
            public int compare(Object o1, Object o2) {
                Date d1 = ((Handoff) o1).getUpdateDate();
                Date d2 = ((Handoff) o2).getUpdateDate();
                return d2.compareTo(d1);
            }
        });

        this.fireTableDataChanged();
    }

    /**
     * Sets the start period.
     * @param start Start time
     */
    public void setStart(long start) {
        this.start = start;
    }

    /**
     * Sets the end period.
     * @param end End time
     */
    public void setEnd(long end) {
        this.end = end;
    }
}
